import ms from 'ms';
import moment from 'moment';
import { FREQUENCY_UNIT_MAP as UNIT } from './constants';
export const number = (() => {
	let format = null;
	try {
		format = new Intl.NumberFormat('en-US').format;
	} catch {
		format = function (num) {
			return num.toLocaleString();
		};
	}
	return n => {
		if (!n) return '0';
		return format(n);
	};
})();

export function percent(t) {
	if (isNaN(t)) return '0%';
	let percentFormat = null;
	try {
		percentFormat = new Intl.NumberFormat('en-US', {
			style: 'percent',
			minimumFractionDigits: 2,
			maximumFractionDigits: 2,
		}).format;
	} catch {
		percentFormat = function (num) {
			return num.toLocaleString('en-US', {
				style: 'percent',
				minimumFractionDigits: 2,
				maximumFractionDigits: 2,
			});
		};
	}
	return percentFormat(t);
}

export function datetime(t, p) {
	try {
		const d = new Date(t || '');
		if (!t || d.getTime() === 0 || !(d instanceof Object)) return '';
		const formatStr = typeof p === 'string' ? p : 'YYYY-MM-DD HH:mm:ss';
		return moment(d).format(formatStr);
	} catch (error) {
		return '';
	}
}

export function numberCompact(t) {
	if (!t) return '0';
	try {
		return new Intl.NumberFormat('zh-CN', {
			notation: 'compact',
		}).format(t);
	} catch {
		try {
			return t.toLocaleString('zh-CN', {
				notation: 'compact',
			});
		} catch {
			return chineseUnit(t);
		}
	}
}

function chineseUnit(num) {
	let value = num;
	let unit = '';
	const step = 100;
	const sizes = ['', '', '万', '百万', '千万', '亿', '百亿', '千亿', '万亿'];
	let i = 0;
	if (value >= 10000) {
		i = Math.floor(Math.log(value) / Math.log(step));
		value = (value / Math.pow(step, i)).toFixed(2);
		unit = sizes[i];
	}
	return value + unit;
}

export const millisecond = (() => {
	let format;
	try {
		format = new Intl.NumberFormat('en', {
			style: 'unit',
			unit: 'millisecond',
		}).format;
	} catch (error) {
		// 兼容 chrome 71, 不支持 style: 'unit'
		format = num => {
			let formattedNum = null;
			try {
				formattedNum = new Intl.NumberFormat('en', {
					unit: 'millisecond',
				}).format(num);
			} catch {
				formattedNum.toLocaleString('en', {
					unit: 'millisecond',
				});
			}
			return `${formattedNum} ms`;
		};
	}

	return x => (Number.isFinite(x - '') ? format(x) : null);
})();

const durationParts = [
	{
		textUnit: '天',
		shortUnit: 'd ',
		ms: 24 * 60 * 60 * 1000,
		isShortUnit: false,
		isTextUnit: true,
	},
	{
		textUnit: '小时',
		shortUnit: ':',
		ms: 60 * 60 * 1000,
		isShortUnit: true,
		isTextUnit: true,
	},
	{
		textUnit: '分钟',
		shortUnit: ':',
		ms: 60 * 1000,
		isShortUnit: true,
		isTextUnit: true,
	},
	{
		textUnit: '秒',
		shortUnit: '',
		ms: 1000,
		isShortUnit: true,
		isTextUnit: false,
	},
];
export function duration(milliseconds, useTextUnit = true) {
	const parts = durationParts.filter(x =>
		!useTextUnit ? x.isShortUnit : x.isTextUnit
	);

	let { ret, current } = parts.reduce(
		(obj, { textUnit, shortUnit, ms }, idx) => {
			const u = useTextUnit ? textUnit : shortUnit;
			if (obj.current >= ms) {
				const isLast = idx === parts.length - 1;
				let n = obj.current / ms;
				n = isLast ? Math.ceil(n) : parseInt(n, 10);
				obj.ret += `${useTextUnit ? n : String(n || 0).padStart(2, '0')}${u}`;
				obj.current = obj.current % ms;
			} else if (useTextUnit ? obj.ret : true) {
				obj.ret += `${useTextUnit ? '0' : '00'}${u}`;
			}
			return obj;
		},
		{
			current: milliseconds,
			ret: '',
		}
	);

	if (!ret && useTextUnit) {
		if (current > 0) {
			current = Math.ceil(current / 1000);
			ret = `${current}秒`;
		} else {
			ret = '0秒';
		}
	}

	return ret;
}

export function timeChange(value) {
	let unit;
	let num;
	if (value) {
		const freq = ms(value);
		unit = value ? freq.replace(/\d*/, '') : 'd';
		num = parseInt(freq.replace(/[a-zA-Z]/, ''), 10);
		if (value % ms('30d') === 0) {
			unit = 'month';
			num = value / ms('30d');
		} else if (value % ms('1w') === 0) {
			unit = 'w';
			num = value / ms('1w');
		}
	}
	// 3小时/5分钟/2天
	return `${num}${UNIT[unit] || '毫秒'}`;
}
